﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Backend.JYD.Common
{
    public class CommonHelper
    {

        #region 校验身份证是否合法

        /// <summary>
        /// 校验身份证是否合法
        /// </summary>
        /// <param name="strIdNo">身份证号码</param>
        /// <returns></returns>
        public static bool CheckPaperNo(string strIdNo)
        {
            // 校验码对应值 
            string[] arrVerifyCode = new string[] { "1", "0", "x", "9", "8", "7", "6", "5", "4", "3", "2" };
            // 加权因子 
            int[] factor = new int[] { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
            //int[] checker = new int[] { 1, 9, 8, 7, 6, 5, 4, 3, 2, 1, 1 };//ctrl+c 来的，不知道啥用。暂时放着
            String strCheckedNo = "";
            int strYear = -1;
            int strMth = -1;
            int strDay = -1;
            try
            {
                //检验位数  
                if (strIdNo.Length == 18)
                {
                    strCheckedNo = strIdNo.Substring(0, 17);
                    //当18位时，还需要校验最后一位校验位
                    //校验18位的最后一位如果不为数字则必须为X.
                    if (!strIdNo.Substring(strIdNo.Length - 1).ToLower().Equals("x") && !NumberHelper.IsNumeric(strIdNo.Substring(strIdNo.Length - 1)))
                        return false;
                }
                else if (strIdNo.Length == 15)//15位证件号码，在年份上由2位补全4位。
                    strCheckedNo = strIdNo.Substring(0, 6) + "19" + strIdNo.Substring(6, 9);
                else //不是15位或者18位报错
                    return false;

                //检验除了最后一位其他必须为数字
                if (!NumberHelper.IsNumeric(strCheckedNo))
                    return false;

                //校验年月日 130682 19800202 233 9
                strYear = Convert.ToInt32(strCheckedNo.Substring(6, 4));
                strMth = Convert.ToInt32(strCheckedNo.Substring(10, 2));
                strDay = Convert.ToInt32(strCheckedNo.Substring(12, 2));

                if (strMth < 1 || strMth > 12 || strDay < 1 || strDay > 31)
                    return false;

                DateTime birthday = new DateTime(strYear, strMth, strDay);
                if (birthday > DateTime.Today)
                    return false;

                //18位号码校验最后一位
                if (strIdNo.Length == 18)
                {
                    int total = 0;
                    for (int i = 0; i < strCheckedNo.Length; i++)
                    {
                        total += Convert.ToInt32(strCheckedNo.Substring(i, 1)) * factor[i];
                    }
                    //计算校验位
                    string verify = arrVerifyCode[total % 11];
                    //判断校验位是否相等
                    if (strIdNo.Substring(strIdNo.Length - 1, 1).ToLower() != verify)
                        return false;
                }
            }
            catch (Exception e)
            {
                e.ToString();
                return false;
            }
            return true;
        }

        /// <summary>
        /// 校验身份证是否合法，并取得该客户生日
        /// </summary>
        /// <param name="strIdNo">身份证号码</param>
        /// <param name="birthday">生日</param>
        /// <returns></returns>
        public static bool CheckPaperNo(string strIdNo, out DateTime birthday)
        {
            birthday = new DateTime();
            // 校验码对应值 
            string[] arrVerifyCode = new string[] { "1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2" };
            // 加权因子 
            int[] factor = new int[] { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
            //int[] checker = new int[] { 1, 9, 8, 7, 6, 5, 4, 3, 2, 1, 1 };//ctrl+c 来的，不知道啥用。暂时放着
            String strCheckedNo = "";
            int strYear = -1;
            int strMth = -1;
            int strDay = -1;
            try
            {
                //检验位数  
                if (strIdNo.Length == 18)
                {
                    strCheckedNo = strIdNo.Substring(0, 17);
                    //当18位时，还需要校验最后一位校验位
                    //校验18位的最后一位如果不为数字则必须为X.
                    if (!strIdNo.Substring(strIdNo.Length - 1).ToLower().Equals("x") && !NumberHelper.IsNumeric(strIdNo.Substring(strIdNo.Length - 1)))
                        return false;

                }
                else if (strIdNo.Length == 15)
                {
                    strCheckedNo = strIdNo.Substring(0, 6) + "19" + strIdNo.Substring(6, 9);
                }
                else//不是15位或者18位报错
                    return false;

                //检验除了最后一位其他必须为数字
                if (!NumberHelper.IsNumeric(strCheckedNo))
                    return false;

                //校验年月日 130682 19800202 233 9
                strYear = Convert.ToInt32(strCheckedNo.Substring(6, 4));
                strMth = Convert.ToInt32(strCheckedNo.Substring(10, 2));
                strDay = Convert.ToInt32(strCheckedNo.Substring(12, 2));

                if (strMth < 1 || strMth > 12 || strDay < 1 || strDay > 31)
                    return false;

                birthday = new DateTime(strYear, strMth, strDay);
                if (birthday > DateTime.Today)
                    return false;

                //18位号码校验最后一位
                if (strIdNo.Length == 18)
                {
                    int total = 0;
                    for (int i = 0; i < strCheckedNo.Length; i++)
                    {
                        total += Convert.ToInt32(strCheckedNo.Substring(i, 1)) * factor[i];
                    }
                    //计算校验位
                    string verify = arrVerifyCode[total % 11];
                    //判断校验位是否相等
                    if (strIdNo.Substring(strIdNo.Length - 1, 1).ToLower() != verify)
                        return false;
                }
            }
            catch (Exception e)
            {
                e.ToString();
                return false;
            }
            return true;
        }
        #endregion

    }
}
